﻿using SuperX.Common;
using SuperX.Common.Collection;
using SuperX.Common.Object;
using SuperX.Helper.TreeUtil;
using SuperX.MiddlewareBase;
using System;
using System.Collections.Generic;
using System.Linq;

namespace SuperX.DataCenterService
{
    public class DataCenterConfig : BasicObjCollection<IBasicObject>
    {
        public DataCenterConfig()
        {
            Name = "RabbitMQ";
        }

        private WebAPIConfig _webAPIConfig;

        private MinioConfig _minioConfig;

        public WebAPIConfig WebAPIConfig
        {
            get => _webAPIConfig ?? (_webAPIConfig = new WebAPIConfig());
            set { _webAPIConfig = value; }
        }

        public MinioConfig MinioConfig
        {
            get => _minioConfig ?? (_minioConfig = new MinioConfig());
            set { _minioConfig = value; }
        }

        private ObjectCollection<DataCenterConfig, RabbitHostConfig> _rabbitMQHosts;

        public ObjectCollection<DataCenterConfig, RabbitHostConfig> RabbitMQHosts
        {
            get { return _rabbitMQHosts ?? (_rabbitMQHosts = new ObjectCollection<DataCenterConfig, RabbitHostConfig>(this)); }
            set
            {
                _rabbitMQHosts = value;
                _rabbitMQHosts.SetParent(this);
            }
        }

        public override IBasicObject this[string name] => RabbitMQHosts[name];

        public override List<string> GetKeys()
        {
            return RabbitMQHosts.Keys.ToList();
        }

        public override List<IBasicObject> GetValues()
        {
            var group = RabbitMQHosts.Values.OfType<IBasicObject>().ToList();
            return group;
        }

        public override bool IsUniqueName(string name, IObjCollection parent)
        {
            if (parent != null)
            {
                return parent.IsUniqueName(name, null);
            }

            return RabbitMQHosts[name] == null;
        }
    }

    public class WebAPIConfig
    {
        /// <summary>
        /// WebApi的IP地址
        /// </summary>
        public string IP { get; set; } = "localhost";

        /// <summary>
        /// WebApi的端口号
        /// </summary>
        public int PORT { get; set; } = 6667;

        /// <summary>
        /// 在程序根目录下反射dll的文件夹，如果为空那就是根目录
        /// </summary>
        //public string DYNAMICLOADPATH { get; set; } = "Service";
    }

    public class MinioConfig
    {
        /// <summary>
        /// Minio访问地址
        /// </summary>
        public string minioEndpoint { get; set; } = "http://localhost:9000";

        /// <summary>
        /// 账号
        /// </summary>
        public string accessKey { get; set; } = "minioadmin";

        /// <summary>
        /// 密码
        /// </summary>
        public string secretKey { get; set; } = "minioadmin";

        /// <summary>
        /// 文件桶
        /// </summary>
        public string bucketName { get; set; } = "momupload";
    }

    public class RabbitHostConfig : BasicObjCollection<IBasicObject>
    {
        /// <summary>
        /// 虚拟机
        /// </summary>
        [Helper.Validation.Empty]
        public string VirtualHost { get; set; } = "/";

        /// <summary>
        /// 发送消息前缀
        /// </summary>
        public string PublishPrefix { get; set; } = "SuperX";

        /// <summary>
        /// 接收消息前缀
        /// </summary>
        public string ReceivePrefix { get; set; }

        /// <summary>
        /// 用户名
        /// </summary>
        public string UserName { get; set; } = "guest";

        /// <summary>
        /// 密码
        /// </summary>
        public string Password { get; set; } = "guest";

        /// <summary>
        /// 连接超时
        /// </summary>
        public int RequestedConnectionTimeout { get; set; } = 3000;

        /// <summary>
        /// 心跳
        /// </summary>
        public ushort Heartbeat { get; set; } = 60;

        /// <summary>
        /// 拓普恢复
        /// </summary>
        public bool TopologyRecoveryEnabled { get; set; } = true;

        /// <summary>
        /// 网络恢复间隔
        /// </summary>
        public TimeSpan NetworkRecoveryInterval { get; set; } = TimeSpan.FromSeconds(5.0);

        /// <summary>
        /// 重连时间
        /// </summary>
        public int ContinuationTimeout { get; set; } = 2000;

        /// <summary>
        /// 自动恢复
        /// </summary>
        public bool AutomaticRecoveryEnabled { get; set; } = true;

        /// <summary>
        /// 是否启用后台线程
        /// </summary>
        public bool UseBackgroundThreadsForIO { get; set; } = true;

        /// <summary>
        /// 最大通道数
        /// </summary>
        public ushort ChannelMax { get; set; } = 2047;

        /// <summary>
        /// 最大请求帧
        /// </summary>
        public uint RequestedFrameMax { get; set; } = 0u;

        /// <summary>
        /// 是否启用
        /// </summary>
        public bool IsEnable { get; set; } = false;

        /// <summary>
        /// 主机
        /// </summary>
        public string HostIP { get; set; }

        /// <summary>
        /// 端口
        /// </summary>
        public int Port { get; set; }

        /// <summary>
        /// 前名称
        /// </summary>
        public string BeforeName { get; set; }

        private ListObjectCollection<RabbitHostConfig, RabbitChannelConfig> _rabbitChannels;

        public ListObjectCollection<RabbitHostConfig, RabbitChannelConfig> ChannelItems
        {
            get => _rabbitChannels ?? (_rabbitChannels = new ListObjectCollection<RabbitHostConfig, RabbitChannelConfig>(this));
            set
            {
                _rabbitChannels = value;
                _rabbitChannels.SetParent(this);
            }
        }

        public override IBasicObject this[string name] => ChannelItems.Values.FirstOrDefault(a => a.Name == name);

        public override List<string> GetKeys()
        {
            return ChannelItems.Values.Select(a => a.Name).ToList();
        }

        public override List<IBasicObject> GetValues()
        {
            return ChannelItems.Values.OfType<IBasicObject>().ToList();
        }

        public override bool IsUniqueName(string name, IObjCollection parent)
        {
            if (parent != null)
            {
                return parent.IsUniqueName(name, null);
            }

            return true;
        }

        /// <summary>
        /// 分组
        /// </summary>
        public Dictionary<string, BaseTreeModel> ChannelGroup
        {
            get => _channelGroup ?? (_channelGroup = new Dictionary<string, BaseTreeModel>());
            set
            {
                _channelGroup = value;
            }
        }

        private Dictionary<string, BaseTreeModel> _channelGroup;

        #region 命名

        /// <summary>
        /// 根据设备类型获取新的设备名字
        /// </summary>
        /// <param name="itemName"></param>
        /// <returns></returns>
        public string GetNewItemName(string itemName)
        {
            string name = "";
            if (!string.IsNullOrEmpty(itemName) && !string.IsNullOrWhiteSpace(itemName))
            {
                itemName = itemName.Replace("-", "");//"-"为非法字符，所以在这里把它替换为空
                itemName = itemName.Replace("/", "");//"/"为非法字符，所以在这里把它替换为空
                itemName = itemName.Replace(" ", "");//" "为非法字符，所以在这里把它替换为空
                name = GetNewItemName(itemName, 1);
            }
            else
            {
                name = GetNewItemName("Item", 1);
            }
            return name;
        }

        /// <summary>
        /// 获取新的设备名字
        /// </summary>
        /// <param name="name"></param>
        /// <param name="itemNo"></param>
        /// <returns></returns>
        public string GetNewItemName(string name, int itemNo)
        {
            string itemName = "";
            if (name.Trim() == "")
            {
                name = "Item";
            }
            try
            {
                itemName = name + itemNo.ToString().Trim();
                if (JudgeItemDevice(ChannelItems, itemName))
                {
                    itemName = GetNewItemName(name, itemNo + 1);
                }
            }
            catch (Exception)
            {
                throw;
            }
            return itemName;
        }

        /// <summary>
        /// 判断传进来的device名字是否已经在集合中存在
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public bool JudgeItemDevice(ListObjectCollection<RabbitHostConfig, RabbitChannelConfig> deviceCollections, string name)
        {
            if (name != null)
            {
                foreach (var item in deviceCollections.Values)
                {
                    var deviceViewModel = item as RabbitChannelConfig;
                    if (item.Name == name)
                    {
                        return true;
                    }
                }

                if (JudgeExistGroupName(name))
                {
                    return true;
                }
                return false;
            }
            else
            {
                return true;
            }
        }

        public bool JudgeExistGroupName(string name)
        {
            bool exist = false;
            if (ChannelGroup.Count > 0)
            {
                foreach (var item in ChannelGroup.Values)
                {
                    if (item.Name == name)
                    {
                        exist = true; break;
                    }
                }
            }
            return exist;
        }

        #endregion 命名

        public void Add(RabbitChannelConfig item)
        {
            if (JudgeExistItem(item))
            {
                item.Name = GetNewItemName(item.Name);
            }
            ChannelItems.Add(item);
        }

        private bool JudgeExistItem(RabbitChannelConfig driver)
        {
            var exists = ChannelItems.Values.FirstOrDefault(a => a.GroupKey == driver.GroupKey && a.Name == driver.Name);
            return exists != null;
        }
    }

    public class RabbitChannelConfig : BasicObject
    {
        /// <summary>
        /// 节点名称
        /// </summary>
        public string GroupKey { get; set; }

        /// <summary>
        /// 前名称
        /// </summary>
        public string BeforeName { get; set; }

        /// <summary>
        /// 角色
        /// </summary>
        [Helper.Validation.Empty]
        public Roles Roles { get; set; }

        /// <summary>
        /// 发送方法
        /// </summary>
        public SendMethod SendMethod { get; set; }

        /// <summary>
        /// Tag名称
        /// </summary>
        [Helper.Validation.Empty]
        public string TagName { get; set; }

        /// <summary>
        /// 自定义队列名称
        /// </summary>
        [Helper.Validation.Empty]
        public string CustomQueueName { get; set; }

        /// <summary>
        /// 是否持久化
        /// </summary>
        public bool Durable { get; set; } = true;

        /// <summary>
        /// 是否独有
        /// </summary>
        public bool Exclusive { get; set; } = false;

        /// <summary>
        /// 是否自动删除
        /// </summary>
        public bool IsAutoDelete { get; set; } = false;

        public override string FullName
        {
            get
            {
                if (Parent != null && Parent.FullName != null && !string.IsNullOrEmpty(GroupKey))
                {
                    return $"{Parent.FullName}.{GroupKey}.{Name}";
                }
                return base.FullName;
            }
        }
    }
}